package com.zonekey.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;

/**
 * @description:
 * @author: 靳俊英
 * @create: 2021-05-18 13:56
 **/
@Configuration
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisTokenStore redisTokenStore;
    /**
     * Spring Boot 默认已经配置好了数据源，程序员可以直接 DI 注入然后使用即可
     */
    @Autowired
    private DataSource dataSource;





    /**
     * {"authorization_code" | "client_credentials" | "password" | "implicit"}?
     * details.setAuthorizedGrantTypes(Arrays.asList("authorization_code",
     * 					"password", "client_credentials", "implicit", "refresh_token"));
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        /**
         *  内部使用了 jdbcClientDetailsService去数据库 oauth_client_details 查询，返回对象 ClientDetails
         *
         *   ClientDetails 的 scope等set集合属性，在映射,去解析数据表时，使用 " ,"去分隔元素完成映射。
         *   ---------------------------------
         *   |    authorized_grant_types     |
         *   -------------------------------
         *   |    password,refresh          |
         *   ------------------------------
         *   	public static String[] commaDelimitedListToStringArray(@Nullable String str) {
         * 		return delimitedListToStringArray(str, ",");
         *        }
         */
        clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
    }

    /**
     * 暴露授权服务器给认证管理器
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
        //拓展"/oauth/token"获取token时的返回信息  //return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token;
        // 配置tokenServices参数
        endpoints.tokenEnhancer(new AirForceAccessTokenConverter());
        endpoints.tokenStore(redisTokenStore);
    }
}
